package org.lcx.pipeline;

import org.lcx.pipeline.bean.PipelineExeption;
import org.lcx.pipeline.bean.PipelineResult;
import org.lcx.pipeline.impl.PipelineChain;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.StringUtils;

import java.text.MessageFormat;

/**
 * Created by lichangxuan on 2017/8/11.
 */
public class SubChainProcessor implements Processor, ApplicationContextAware {

    public final Log log = LogFactory.getLog(this.getClass());

    private static ApplicationContext ctx;

    // 要调用的子链的名称
    private String subChainName;

    // 子链调用成功后的返回值（当调用完子链之后，还需要继续调用时就会使用到，默认为-9999,意思是需要手工强制配置)
    private int successRetCode = -9999;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ctx = applicationContext;
    }

    @Override
    public int runProcess(Object obj, PipelineResult pipeResult) throws PipelineExeption {
        if (StringUtils.isEmpty(subChainName)) {
            String msgFormat = "processor {0} , sub pipelineChain(name:{1})未定义";
            throw new PipelineExeption(MessageFormat.format(msgFormat, this.getClass().getSimpleName(), subChainName));
        }

        PipelineChain subChain = null;
        try {
            subChain = ctx.getBean(subChainName, PipelineChain.class);
        } catch (BeansException e) {
            String msgFormat = "processor {0} , sub pipelineChain(name:{1})未找到，或类型不正确";
            throw new PipelineExeption(MessageFormat.format(msgFormat, this.getClass().getSimpleName(), subChainName));
        }

        boolean rolledBack = subChain.runProcess(pipeResult, obj);
        if (log.isDebugEnabled()) {
            String msgFormat = "processor {0} , sub pipelineChain(name:{1})执行完成, 事务回滚状态: {2}";
            log.debug(MessageFormat.format(msgFormat, this.getClass().getSimpleName(), subChainName, rolledBack));
        }

        return rolledBack ? STOP_CHAIN_EXECUTION_AND_ROLLBACK : getSuccessRetCode();
    }

    public String getSubChainName() {
        return subChainName;
    }

    public void setSubChainName(String subChainName) {
        this.subChainName = subChainName;
    }

    public int getSuccessRetCode() {
        return successRetCode;
    }

    public void setSuccessRetCode(int successRetCode) {
        this.successRetCode = successRetCode;
    }
}
